﻿
package com.thorqq.magictimer;

import com.thorqq.magictimer.timeLoop.TimerMgr;
import com.thorqq.magictimer.util.Util;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnErrorListener;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;

/***
 * Manages alarms and vibe. Runs as a service so that it can continue to play if
 * another activity overrides the AlarmAlert dialog.
 */
// Klaxon:喇叭。 在后台播放闹铃和震动
public class MediaPlaySvc extends Service
{
//    private static final long[] sVibratePattern = new long[] { 500, 500 };

    private boolean mPlaying = false;
    private MediaPlayer mMediaPlayer;
    private TelephonyManager mTelephonyManager;
    private int mInitialCallState;
    private String mMusicPath;
    private Boolean mLoop;
    // Internal messages

    private PhoneStateListener mPhoneStateListener = new PhoneStateListener()
    {
        @Override
        public void onCallStateChanged(int state, String ignored)
        {
            // The user might already be in a call when the alarm fires. When
            // we register onCallStateChanged, we get the initial in-call state
            // which kills the alarm. Check against the initial call state so
            // we don't kill the alarm during a call.
            // 如果有通话进来，则停止闹铃
            if (state != TelephonyManager.CALL_STATE_IDLE && state != mInitialCallState)
            {
                stopSelf();
            }
        }
    };

    @Override
    public void onCreate()
    {
        // Listen for incoming calls to kill the alarm.
        // 监听通话状态
        mTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
    }

    @Override
    public void onDestroy()
    {
        // 停止闹铃
        stop();
        // Stop listening for incoming calls.
        // 停止监听来电状态
        mTelephonyManager.listen(mPhoneStateListener, 0);
    }

    @Override
    public IBinder onBind(Intent intent)
    {
        return null;
    }

    // 客户端调用 startService(Intent)启动服务的时候会调用此方法
    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        // No intent, tell the system not to restart us.
        if (intent == null)
        {
            stopSelf();
            return START_NOT_STICKY;
        }

        mMusicPath = intent.getExtras().getString(TimerMgr.ALARM_INTENT_MUSIC_PATH);
        mLoop = intent.getExtras().getBoolean(TimerMgr.ALARM_INTENT_MUSIC_LOOP, false);

        // 开始播放
        play();
        // Record the initial call state here so that the new alarm has the
        // newest state.
        // 记录当前的呼叫状态
        mInitialCallState = mTelephonyManager.getCallState();

        return START_STICKY;
    }

    private void play()
    {
        // stop() checks to see if we are already playing.
        // 先停止铃声和震动
        stop();

        // TODO: Reuse mMediaPlayer instead of creating a new one and/or use
        // RingtoneManager.
        mMediaPlayer = new MediaPlayer();
        // 错误捕获
        mMediaPlayer.setOnErrorListener(new OnErrorListener()
        {
            public boolean onError(MediaPlayer mp, int what, int extra)
            {
                mp.stop();
                mp.release();
                mMediaPlayer = null;
                return true;
            }
        });

        try
        {
            // Check if we are in a call. If we are, use the in-call alarm
            // resource at a low volume to not disrupt the call.
            // 检查一下是否正在通话，如果正在通话，则使用低音量的通话内铃声，不打断通话
            mMediaPlayer.setDataSource(mMusicPath);
            
            // 开始播放闹铃
            startAlarm(mMediaPlayer);
        } catch (Exception ex)
        {
            //TODO 这里最好要提示用户出现什么错误
            Util.log_ex(ex);
        }

        // 在指定时间后删除闹铃声音
        mPlaying = true;
    }

    // Do the common stuff when starting the alarm.
    // 开始播放闹铃
    private void startAlarm(MediaPlayer player) throws java.io.IOException,
            IllegalArgumentException, IllegalStateException
    {
        final AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        // do not play alarms if stream volume is 0
        // (typically because ringer mode is silent).
        if (audioManager.getStreamVolume(AudioManager.STREAM_ALARM) != 0)
        {
            player.setAudioStreamType(AudioManager.STREAM_ALARM);
            player.setLooping(mLoop);
            player.prepare();
            player.start();
        }
    }

    /***
     * 停止铃声
     */
    public void stop()
    {
        if (mPlaying)
        {
            mPlaying = false;

            // 停止播放铃声
            if (mMediaPlayer != null)
            {
                mMediaPlayer.stop();
                mMediaPlayer.release();
                mMediaPlayer = null;
            }
        }
    }


}
